
package com.tools.cleanmaster.ui.card.animator;

import android.content.Context;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LayoutAnimationController;
import android.view.animation.LinearInterpolator;
import android.widget.ListView;
import android.widget.RelativeLayout;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.PropertyValuesHolder;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.nineoldandroids.view.ViewHelper;
import com.nineoldandroids.view.animation.AnimatorProxy;
import com.tools.cleanmaster.CleanApplication;
import com.tools.cleanmaster.R;
import com.tools.cleanmaster.store.GlobalConfigSharedPrefManager;
import com.tools.cleanmaster.utils.Utils;

import java.util.ArrayList;

public class AnimatorHelper {
    public interface ListItemAnimListener {
        void onAnimationStart();

        void onAnimationGoing();

        void onAnimationEnd();
    }

    public interface ItemAnimListener {
        void onAnimationEnd(View view);
    }

    private static final int ARROW_SHOW_MAX_NUMBER = 2;
    private static final long TIPS_ARROW_ANIM_ONE_TIME = 800;
    private static final long TRASH_ANIM_ONE_TIME = 500;

    /**
     * list alpha飞入飞出动画
     *
     * @param listView
     * @param duration 时间长短
     * @param isToUp   true 从原位置往上飞出;false 从下面部分飞到原位置
     */
    public static void animateVisibleItemOut(ListView listView, long duration, boolean isToUp,
                                             final com.nineoldandroids.animation.AnimatorListenerAdapter listener) {
        if (listView == null) {
            return;
        }
        int childCount = listView.getChildCount();

        for (int i = 0; i < childCount; i++) {
            View child = listView.getChildAt(i);
            Rect outRect = new Rect();
            child.getHitRect(outRect);
            ViewHelper.setPivotX(child, 0);
            PropertyValuesHolder transY;

            if (isToUp) {
                transY = PropertyValuesHolder.ofFloat("translationY", 0, -outRect.bottom);
            } else {
                transY = PropertyValuesHolder.ofFloat("translationY", outRect.bottom, 0);
            }

            Object target = AnimatorProxy.NEEDS_PROXY ? AnimatorProxy.wrap(child) : child;
            final ObjectAnimator objectAnimHolder = ObjectAnimator.ofPropertyValuesHolder(target,
                    transY);

            objectAnimHolder.setDuration(duration * (i + 1));
            objectAnimHolder.setInterpolator(new AccelerateDecelerateInterpolator());
            objectAnimHolder.start();
            listView.postDelayed(new Runnable() {

                @Override
                public void run() {
                    listener.onAnimationEnd(objectAnimHolder);
                }
            }, duration * childCount);
        }
    }

    public static void compressionView(final View originView, final com.nineoldandroids.animation.AnimatorListenerAdapter listener) {
        int height = originView.getHeight();
        final ViewGroup.LayoutParams layoutParams = originView
                .getLayoutParams();

        ValueAnimator valueAnimator = ValueAnimator.ofInt(height, 0);
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                int animatorValue = (Integer) animator.getAnimatedValue();
                layoutParams.height = animatorValue;
                originView.setLayoutParams(layoutParams);

            }
        });

        valueAnimator.addListener(new com.nineoldandroids.animation.AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (listener != null) {
                    listener.onAnimationStart(animation);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (listener != null) {
                    listener.onAnimationEnd(animation);
                }
            }
        });
        valueAnimator.start();
    }

    public static void startTopTipAnim(final View srcView, final View destView, long duration) {
        final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(0, 1);
        alphaAnimator.setInterpolator(new LinearInterpolator());
        alphaAnimator.setDuration(duration);
        alphaAnimator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                float animatorValue = (Float) animator.getAnimatedValue();
                ViewHelper.setAlpha(srcView, animatorValue);
                ViewHelper.setAlpha(destView, 1 - animatorValue);
            }
        });

        alphaAnimator.addListener(new com.nineoldandroids.animation.AnimatorListenerAdapter() {

            @Override
            public void onAnimationStart(Animator animation) {
                srcView.setVisibility(View.VISIBLE);
            }
        });
        alphaAnimator.start();
    }

    public static void startCardTransAnim(final View cardView, long duartion,
                                          final AnimatorListenerAdapter listener) {
        final RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) cardView
                .getLayoutParams();
        final int topMargin = layoutParams.topMargin;
        Interpolator accelerataInterpolator = new DecelerateInterpolator();
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, 0);
        valueAnimator.setDuration(duartion);
        valueAnimator.setInterpolator(accelerataInterpolator);
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                float animatorValue = (Float) animator.getAnimatedValue();
                layoutParams.topMargin = (int) (topMargin * animatorValue);
                cardView.setLayoutParams(layoutParams);
                if (listener != null) {
                    listener.onAnimationUpdate(animatorValue);
                }
            }
        });
        valueAnimator.addListener(new com.nineoldandroids.animation.AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (listener != null) {
                    listener.onAnimationEnd(animation);
                }
            }

            @Override
            public void onAnimationStart(Animator animation) {
                if (listener != null) {
                    listener.onAnimationStart(animation);
                }
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                if (listener != null) {
                    listener.onAnimationRepeat(animation);
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                if (listener != null) {
                    listener.onAnimationCancel(animation);
                }
            }
        });
        valueAnimator.start();
    }

    /**
     * 用于结果页title动画
     *
     * @param view
     * @param duration
     * @param listenerAdapter
     */
    private static void startHeaderViewAnim(View view, long duration,
                                            final com.nineoldandroids.animation.AnimatorListenerAdapter listenerAdapter) {
        ValueAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f);
        alpha.setDuration(duration);
        alpha.addListener(new com.nineoldandroids.animation.AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (listenerAdapter != null) {
                    listenerAdapter.onAnimationStart(animation);
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                if (listenerAdapter != null) {
                    listenerAdapter.onAnimationCancel(animation);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (listenerAdapter != null) {
                    listenerAdapter.onAnimationEnd(animation);
                }

            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                if (listenerAdapter != null) {
                    listenerAdapter.onAnimationRepeat(animation);
                }
            }
        });
        alpha.start();
    }

    /**
     * 用于界面tips动画
     *
     * @param view
     */
    public static void startTipAnimation(View view, long duration, int repeatCount,
                                         com.nineoldandroids.animation.AnimatorListenerAdapter listenerAdapter) {
        ValueAnimator translateY = ObjectAnimator.ofFloat(view, "translationY", 0, -20);
        translateY.setDuration(duration);
        translateY.setRepeatCount(1);
        translateY.addListener(listenerAdapter);
        translateY.start();
    }

    /**
     * 执行listview 里item 和header动画
     *
     * @param cardListView
     * @param headerView
     */
    public static void doListViewAnimation(ListView cardListView, final View headerView) {
        doListViewAnimation(cardListView, headerView, null);
    }

    /**
     * 处理卡片页listview 包含 header 动效,包含监听
     *
     * @param cardListView
     * @param headerView
     * @param listener
     */
    public static void doListViewAnimation(final ListView cardListView, final View headerView, final ListItemAnimListener listener) {
        final LayoutAnimationController controller = getListItemAnimControler();
        cardListView.setVisibility(View.VISIBLE);
        cardListView.setLayoutAnimation(controller);
        cardListView.setLayoutAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                if (listener != null) {
                    listener.onAnimationStart();
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (listener != null) {
                    listener.onAnimationGoing();
                }
                if (headerView != null) {
                    headerView.setVisibility(View.VISIBLE);
                    cardListView.setVerticalScrollBarEnabled(true);
                    if (listener != null) {
                        listener.onAnimationEnd();
                    }
                } else {
                    if (listener != null) {
                        listener.onAnimationEnd();
                    }
                }
            }

        });
    }

    private static LayoutAnimationController getListItemAnimControler() {
        Animation animation = AnimationUtils.loadAnimation(CleanApplication.getInstance(),
                R.anim.diagnostic_card_item_anim);

        LayoutAnimationController layoutAnimController = new LayoutAnimationController(animation);
        layoutAnimController.setOrder(LayoutAnimationController.ORDER_NORMAL);
        layoutAnimController.setDelay(0.15f);
        return layoutAnimController;
    }

    /**
     * 用于卡片页listview header上的view效果
     */
    public static void startHeaderViewAnim(final View leftView, final View rightView,
                                           long duration, final com.nineoldandroids.animation.AnimatorListenerAdapter listenerAdapter) {

        Interpolator accInterpolator = new AccelerateInterpolator();
        ValueAnimator scaleX = ObjectAnimator.ofFloat(leftView, "scaleX", 0, 1);
        scaleX.setDuration(duration);
        scaleX.setInterpolator(accInterpolator);

        ValueAnimator scaleY = ObjectAnimator.ofFloat(leftView, "scaleY", 0, 1);
        scaleY.setDuration(duration);
        scaleY.setInterpolator(accInterpolator);

        ValueAnimator alpha = ObjectAnimator.ofFloat(leftView, "alpha", 0, 1);
        alpha.setDuration(duration);
        alpha.setInterpolator(accInterpolator);
        ValueAnimator tvscaleX = ObjectAnimator.ofFloat(
                rightView,
                "translationX",
                Utils.dip2px(CleanApplication.getInstance(), CleanApplication.getInstance().getResources()
                        .getDimension(R.dimen.toolbox_small_card_right_width)), 0);
        tvscaleX.setDuration(duration);
        tvscaleX.setInterpolator(accInterpolator);
        ValueAnimator tvalpha = ObjectAnimator.ofFloat(rightView, "alpha", 0, 1);
        tvalpha.setDuration(duration);
        tvalpha.setInterpolator(accInterpolator);

        AnimatorSet mGoldFadeInAnimatorSet = new AnimatorSet();
        mGoldFadeInAnimatorSet.play(scaleX).with(scaleY).with(alpha).with(tvscaleX).with(tvalpha);
        mGoldFadeInAnimatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (listenerAdapter != null) {
                    listenerAdapter.onAnimationEnd(animation);
                }
                leftView.clearAnimation();
                rightView.clearAnimation();
            }

            @Override
            public void onAnimationStart(Animator animation) {
                if (listenerAdapter != null) {
                    listenerAdapter.onAnimationStart(animation);
                }
                leftView.setVisibility(View.VISIBLE);
                rightView.setVisibility(View.VISIBLE);
                ViewHelper.setPivotY(leftView, leftView.getHeight() / 2);
                ViewHelper.setPivotX(leftView, leftView.getWidth() / 2);
            }
        });
        mGoldFadeInAnimatorSet.start();
    }

    public static void listItemDismiss(final View dismissView, final int dismissPosition,
                                       long duration,
                                       final AnimatorListener listener) {
        final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
        final int originalHeight = dismissView.getHeight();

        ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 0).setDuration(duration);
        animator.start();

        animator.addListener(new com.nineoldandroids.animation.AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {

                ViewHelper.setAlpha(dismissView, 1f);
                ViewHelper.setTranslationX(dismissView, 0);
                ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
                lp.height = originalHeight;
                dismissView.setLayoutParams(lp);

                if (listener != null) {
                    listener.onAnimationEnd(animation);
                }
            }
        });

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                lp.height = (Integer) valueAnimator.getAnimatedValue();
                dismissView.setLayoutParams(lp);
            }
        });

    }

    public static void animateVisibleItemOut(final View view, int width, long duration,
                                             final ItemAnimListener listener) {
        if (view == null) {
            return;
        }
        ValueAnimator translateX = ObjectAnimator.ofFloat(view, "translationX", 0, -width);
        translateX.setDuration(duration);
        translateX.setInterpolator(new AccelerateDecelerateInterpolator());
        translateX.start();
        translateX.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                if (listener != null) {
                    listener.onAnimationEnd(view);
                }
            }
        });
    }

    /**
     * 展示首页游戏加速箭头浮动动画
     */
    public static void startTipsArrowAnim(Context context, final View mSlideArrow) {
        int count = 1;
        // 第一次显示2次,以后进入结果页都为一次
        if (0 == GlobalConfigSharedPrefManager.getArrowShowNumber(CleanApplication.getInstance())) {
            count = ARROW_SHOW_MAX_NUMBER;
            GlobalConfigSharedPrefManager.setArrowShowNumber(CleanApplication.getInstance(), 1);
        }
        AnimatorSet mTipsArrowAnimatorSet = null;
        Interpolator accInterpolator = new DecelerateInterpolator();
        float scaleProportion = 0.88f;


        if (mSlideArrow != null) {
            ValueAnimator translateX = ObjectAnimator.ofFloat(mSlideArrow, "translationX", 0, 0);
            translateX.setDuration(TIPS_ARROW_ANIM_ONE_TIME);
            translateX.setInterpolator(accInterpolator);

            ValueAnimator translateY = ObjectAnimator.ofFloat(mSlideArrow, "translationY", 0,
                    -Utils.dip2px(context, 7));
            translateY.setDuration(TIPS_ARROW_ANIM_ONE_TIME);
            translateY.setInterpolator(accInterpolator);

            ValueAnimator scaleX = ObjectAnimator.ofFloat(mSlideArrow, "scaleX", 1, scaleProportion);
            scaleX.setDuration(TIPS_ARROW_ANIM_ONE_TIME);
            scaleX.setInterpolator(accInterpolator);

            ValueAnimator scaleY = ObjectAnimator.ofFloat(mSlideArrow, "scaleY", 1, scaleProportion);
            scaleY.setDuration(TIPS_ARROW_ANIM_ONE_TIME);
            scaleY.setInterpolator(accInterpolator);

            ValueAnimator alpha = ObjectAnimator.ofFloat(mSlideArrow, "alpha", 1, 0f);
            alpha.setDuration(TIPS_ARROW_ANIM_ONE_TIME);
            alpha.setInterpolator(accInterpolator);
            mTipsArrowAnimatorSet = new AnimatorSet();
            mTipsArrowAnimatorSet.play(translateX).with(translateY).with(scaleX).with(scaleY)
                    .with(alpha);
            mTipsArrowAnimatorSet.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mSlideArrow.clearAnimation();
                    mSlideArrow.setVisibility(View.GONE);

                }

                @Override
                public void onAnimationStart(Animator animation) {
                    mSlideArrow.setVisibility(View.VISIBLE);
                    Animation fadeInAnimation = AnimationUtils.loadAnimation(
                            CleanApplication.getInstance(),
                            R.anim.access_finish_slide_arrow_fade_in);
                    mSlideArrow.startAnimation(fadeInAnimation);
                }
            });

            ArrayList<Animator> childAnimations = mTipsArrowAnimatorSet.getChildAnimations();
            for (Animator childAnimator : childAnimations) {
                ValueAnimator valueAnim = (ValueAnimator) childAnimator;
                if (ARROW_SHOW_MAX_NUMBER == count) {
                    valueAnim.setRepeatMode(ValueAnimator.RESTART);
                    valueAnim.setRepeatCount(1);
                }
            }
            mTipsArrowAnimatorSet.start();
        }
    }

    public static void startTrashViewInAnim(final View v) {
        ValueAnimator alpha = ObjectAnimator.ofFloat(v, "alpha", 1, 0f);
        alpha.setDuration(TRASH_ANIM_ONE_TIME);
        alpha.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                v.setVisibility(View.INVISIBLE);
            }
        });
        alpha.start();
    }

    public static void startTrashViewViAnim(final View v, AnimatorListenerAdapter listenerAdapter) {
        ValueAnimator alpha = ObjectAnimator.ofFloat(v, "alpha", 0, 1f);
        alpha.setDuration(TRASH_ANIM_ONE_TIME);
        alpha.addListener(listenerAdapter);
        alpha.start();
    }


    public interface ShrinkExplansionListener {
        void update(float scaleSize);

    }

    /**
     * VirusScanView向上缩小移动动画
     *
     * @param context
     * @param view
     * @param duration      动画执行时间
     * @param interpolator  控制器
     * @param transDistance 动画移动距离
     */
    public static AnimatorSet startZoomAnim(Context context, View view, long duration,
                                            Interpolator interpolator, int transDistance) {
        return startZoomAnim(context, view, duration, interpolator, transDistance, 1, 0.75f, null);
    }

    /**
     * VirusScanView向上缩小移动动画
     *
     * @param context
     * @param view
     * @param duration      动画执行时间
     * @param interpolator  控制器
     * @param transDistance 动画移动距离
     * @param fromScale     缩放比例
     */
    public static AnimatorSet startZoomAnim(Context context, View view, long duration,
                                            Interpolator interpolator, int transDistance,
                                            float fromScale, float toScale,
                                            final AnimatorHelper.ShrinkExplansionListener listener) {
        return startZoomAnim(context, view, duration, interpolator, transDistance,
                fromScale, toScale, listener, null);
    }

    /**
     * VirusScanView向上缩小移动动画
     *
     * @param context
     * @param view
     * @param duration         动画执行时间
     * @param interpolator     控制器
     * @param transDistance    动画移动距离
     * @param fromScale        缩放比例
     * @param animatorListener 提供一种监听器，防止调用者通过addLListener监听不到onStart方法
     */
    public static AnimatorSet startZoomAnim(Context context, View view, long duration,
                                            Interpolator interpolator, int transDistance,
                                            float fromScale, float toScale,
                                            final ShrinkExplansionListener listener,
                                            com.nineoldandroids.animation.AnimatorListenerAdapter animatorListener) {
        if (view == null) {
            return null;
        }
        ViewHelper.setPivotX(view, view.getWidth() / 2);
        ViewHelper.setPivotY(view, 0);
        ValueAnimator scanConScaleX = ObjectAnimator.ofFloat(view, "scaleX", fromScale, toScale);
        scanConScaleX.setDuration(duration);
        scanConScaleX.setInterpolator(interpolator);

        ValueAnimator scanConScaleY = ObjectAnimator.ofFloat(view, "scaleY", fromScale, toScale);
        scanConScaleY.setDuration(duration);
        scanConScaleY.setInterpolator(interpolator);

        ValueAnimator scanConTransX = ObjectAnimator.ofFloat(view, "translationX", 0, 0);
        scanConTransX.setDuration(duration);
        scanConTransX.setInterpolator(interpolator);

        ValueAnimator scanConTransY = ObjectAnimator.ofFloat(view, "translationY", 0, -transDistance);
        scanConTransY.setDuration(duration);
        scanConTransY.setInterpolator(interpolator);

        if (listener != null) {
            scanConScaleX.addUpdateListener(new AnimatorUpdateListener() {

                @Override
                public void onAnimationUpdate(ValueAnimator animator) {

                    float scaleSize = (Float) animator.getAnimatedValue();
                    listener.update(scaleSize);

                }
            });
        }

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(scanConScaleX).with(scanConScaleY).with(scanConTransX)
                .with(scanConTransY);
        if (animatorListener != null) {
            animatorSet.addListener(animatorListener);
        }
        animatorSet.start();
        return animatorSet;
    }

    /**
     * VirusScanView向下放大移动动画
     *
     * @param view
     * @param duration     动画执行时间
     * @param interpolator 控制器
     * @return
     */
    public static AnimatorSet startZoomOutAnim(Context context, View view, long duration,
                                               Interpolator interpolator, int transDistance) {
        return startZoomOutAnim(context, view, duration, interpolator, transDistance, 0.75f, 1);
    }

    /**
     * VirusScanView向下放大移动动画
     *
     * @param view
     * @param duration     动画执行时间
     * @param interpolator 控制器
     * @param fromScale    放大比例
     * @return
     */
    public static AnimatorSet startZoomOutAnim(Context context, View view, long duration, Interpolator interpolator, int transDistance, float fromScale, float toScale) {

        if (view == null) {
            return null;
        }

        ViewHelper.setPivotX(view, view.getWidth() / 2);
        ViewHelper.setPivotY(view, 0);
        ValueAnimator scanConScaleX = ObjectAnimator.ofFloat(view, "scaleX", fromScale, toScale);
        scanConScaleX.setDuration(duration);
        scanConScaleX.setInterpolator(interpolator);

        ValueAnimator scanConScaleY = ObjectAnimator.ofFloat(view, "scaleY", fromScale, toScale);
        scanConScaleY.setDuration(duration);
        scanConScaleY.setInterpolator(interpolator);

        ValueAnimator scanConTransX = ObjectAnimator.ofFloat(view, "translationX", 0, 0);
        scanConTransX.setDuration(duration);
        scanConTransX.setInterpolator(interpolator);

        ValueAnimator scanConTransY = ObjectAnimator.ofFloat(view, "translationY", -transDistance, 0);
        scanConTransY.setDuration(duration);
        scanConTransY.setInterpolator(interpolator);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(scanConScaleX).with(scanConScaleY).with(scanConTransX)
                .with(scanConTransY);
        animatorSet.start();
        return animatorSet;
    }

}
